**Инфраструктура открытых ключей и сертификаты в ALD Pro**
==========================================================

Для обеспечения минимального уровня безопасности при взаимодействии с доменными службами используются сертификаты стандарта **X.509 (RFC 5280)**. Эти сертификаты, в совокупности с соответствующими службами и утилитами, реализуют **Инфраструктуру открытых ключей (PKI, Public Key Infrastructure)**.

Что такое **PKI**?
------------------

**Инфраструктура открытых ключей (PKI)** — это механизм обеспечения безопасной коммуникации, идентификации, аутентификации и авторизации на основе сертификатов стандарта **X.509**.

**PKI** построена на иерархии доверия удостоверяющим центрам (УЦ). Фундаментальные условия безопасности PKI включают:

1. Защиту закрытого ключа (доступ к нему должен быть исключён для третьих лиц).
2. Цепочки доверия — иерархическую структуру сертификатов, где каждый уровень подписывает следующий.

Узлы цепочки доверия
------------------------

Цепочка доверия включает следующие узлы:

- **Корневой сертификат (Root Certificate)**:

  Сертификат, которому изначально доверяют все участники взаимодействия. Доверие может быть основано на политике предприятия или предустановленных настройках хранилища сертификатов. Корневой УЦ находится в начале цепочки доверия.

  .. important::

     Корневой сертификат должен храниться в защищённом месте, так как его компрометация делает всю цепочку доверия недействительной.

- **Промежуточные сертификаты (Intermediate Certificates)**:

  Сертификаты, подписанные корневым УЦ и расположенные между корневым и конечным сертификатом. Они позволяют делегировать выпуск конечных сертификатов без риска компрометации корневого закрытого ключа.

В современных системах обычно используются цепочки доверия с 2–3 промежуточными сертификатами, хотя технически ограничений на их количество нет.

- **Конечный сертификат ("на устройство" или "на пользователя")**:

  Последнее звено цепочки. Используется непосредственно для аутентификации устройств или пользователей. Проверка конечного сертификата включает проверку всей цепочки вышестоящих сертификатов. Если хотя бы один узел цепочки недостоверен, конечный сертификат считается недоверенным и отклоняется.

.. _kerberos-pkinit:

Kerberos PKINIT
---------------

По умолчанию при развёртывании ALD Pro создаётся самоподписанный корневой сертификат (**Self-Signed CA**).

Для повышения безопасности и удобства управления рекомендуется использовать промежуточный сертификат (Sub CA). Если в вашей инфраструктуре уже используется внешний удостоверяющий центр, ALD Pro позволяет импортировать его сертификаты и работать с ними.

**Kerberos PKINIT** (Public Key Cryptography for Initial Authentication in Kerberos) — расширение протокола Kerberos, позволяющее выполнять начальную аутентификацию с помощью сертификатов X.509 вместо пароля.

В ALD Pro механизм **PKINIT** используется для поддержки двухфакторной аутентификации (в том числе со смарт-картами и токенами) и тесно интегрирован с **SSSD** через правила certmap.

Подробнее о протоколе PKINIT можно прочитать в RFC 4556 и документации MIT Kerberos.

SSSD Certmap
------------

В рамках домена **ALD Pro** механизм сопоставления сертификатов реализован через **sss-certmap** (встроенный в **SSSD**).  

Правила сопоставления и отображения сертификатов (**certmap**) позволяют установить соответствие между данными сертификата X.509 и учётной записью пользователя в домене. Это особенно важно при использовании аутентификации по сертификатам (в том числе через **Kerberos PKINIT**).

Подробнее о синтаксисе правил ``matchrule`` и ``maprule``, а также о работе механизма читайте в документации SSSD:

.. seealso::

   `sss-certmap(5) <https://manpages.debian.org/experimental/libsss-certmap0/sss-certmap.5.en.html>`_

.. note::

   В домене **ALD Pro** правила certmap задаются не напрямую в файле ``sssd.conf``, а через команду ``ipa certmaprule-add``.

По умолчанию в ALD Pro при установке первого контроллера домена создаётся самоподписанный корневой сертификат (**Self-Signed CA**).

Для повышения безопасности рекомендуется использовать промежуточный сертификат (Sub CA) или сертификаты от внешнего удостоверяющего центра.

Правила сопоставления сертификатов
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Сертификаты **X.509** содержат различную информацию о владельце (``Subject``) и издателе (``Issuer``). Однако не существует единого стандарта, какое именно поле сертификата должно использоваться для идентификации пользователя в операционной системе или каталоге.

В одних средах используется ``Common Name`` (``CN``) из поля ``Subject``. В других, особенно интегрированных с Active Directory, часто используется ``User Principal Name`` (``UPN``) или sAMAccountName, которые могут быть закодированы в поле ``Subject Alternative Name`` (``SAN``). Иногда требуется сопоставление на основе комбинации полей сертификата (например, ``Subject`` и ``Issuer``). Имя пользователя в системе может отличаться от идентификатора в сертификате (например, ``j.doe`` в сертификате должно отображаться на ``jdoe`` в **Linux**).

Правила certmap предоставляют гибкий механизм для решения этих задач, позволяя администратору точно указать, как извлечь идентификатор пользователя из сертификата и как его использовать для поиска.

Работа правил certmap в SSSD
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**Получение сертификата**: Когда пользователь пытается аутентифицироваться с помощью сертификата (например, через ``PAM`` с модулем ``pam_sss`` или через **GSSAPI**), сертификат передается демону **SSSD**.

**Применение правил**: **SSSD** обрабатывает настроенные правила certmap для соответствующего домена в порядке их приоритета.

**Сопоставление** (``matchrule``): Каждое правило сначала проверяется с помощью ``matchrule``. Это правило определяет, применим ли данный набор правил к представленному сертификату. Обычно здесь проверяются поля ``Issuer`` (издатель) или ``Subject`` (владелец). Если сертификат не соответствует ``matchrule``, **SSSD** переходит к следующему правилу ``certmap``.

**Отображение** (``maprule``): Если сертификат соответствует ``matchrule``, **SSSD** применяет ``maprule``. Это правило определяет, *какие данные* извлечь из сертификата и *как* их использовать. Как правило, maprule формирует строку, которая затем используется для поиска пользователя в бэкенде (например, **LDAP**-фильтр или просто имя пользователя). Специальный плейсхолдер (``data``) используется для вставки данных, извлеченных из сертификата согласно синтаксису правила.

**Поиск пользователя**: **SSSD** использует результат maprule для поиска пользователя в соответствующем домене (**LDAP**, **AD**, **IPA** и т.д.).

**Аутентификация**: Если пользователь найден и проверка сертификата (например, через **OCSP**/**CRL**) успешна, аутентификация считается пройденной.

Особенности использования сертификатов в ALD Pro
====================================================

Служба каталогов **ALD Pro** использует сертификаты со сроком действия **10 лет**, которые выпускаются от сертификата домена.

**Сертификат домена** - по умолчанию это **самоподписанный (self-signed)** корневой сертификат, выпускаемый на **20 лет**. Ключевая пара корневого сертификата генерируется автоматически при продвижении первого контроллера домена.

Основные сервисы, работающие с сертификатами в ALD Pro
----------------------------------------------------------

Для обеспечения безопасной и корректной работы домена сертификаты сервисов контроллеров домена должны быть доверенными для всех хостов и служб внутри Службы каталогов (домена). Это гарантирует целостность и конфиденциальность данных при взаимодействии между компонентами.

Сервисы, которым необходимы сертификаты для работы с настройками по умолчанию:

-  **LDAP** (``389ds``) — протоколы ``ldaps`` и ``ldap`` + **StartTLS**.

-  **KDC** (``krb5-kdc``) — протокол **Kerberos** (расширение **PKINIT**).

-  **WEB** + **API** (**Apache2** + **Python**) — протокол **HTTPS**.

Сервис LDAP (389ds)
-----------------------

Сертификаты для сервиса **LDAP** хранятся в базе данных **NSSDB** (Network Security Services Database) по пути ``/etc/dirsrv/slapd-<realm>``.

.. code-block:: text

   Файлы базы данных:
   - cert9.db  — база данных сертификатов (формат SQLite)
   - key4.db   — база данных закрытых ключей (формат SQLite)

**NSSDB** использует формат **SQLite** для хранения сертификатов. Сертификаты внутри базы хранятся в формате контейнера **PKCS#11**. Просмотреть их можно стандартной утилитой ``certutil``:

.. code-block:: bash

   # certutil -L -d /etc/dirsrv/slapd-ALD-COMPANY-LAN/

Результат выполнения команды:

.. code-block:: console

   Certificate Nickname Trust Attributes
   SSL,S/MIME,JAR/XPI
   local-dc1.ald.company.lan u,u,u
   CA Signing Certificate C,,

Флаги доверия означают:

c — валидный УЦ;

C — доверенный УЦ для выпуска сертификатов "на устройство" (включает c);

T — доверенный УЦ для выпуска и авторизации сертификатов "на пользователя" (включает c);

u — динамический флаг, указывающий, что для данного сертификата есть связанный закрытый ключ.

На примере выше мы видим доверенный корневой сертификат УЦ и сертификат устройства со связанным ключом.

Сервис KDC (krb5-kdc)
-------------------------

**KDC** использует сертификаты стандарта **X.509** для реализации расширения **PKINIT** (**Public Key Cryptography for Initial Authentication in Kerberos**). **PKINIT** позволяет использовать криптографию с открытым ключом на этапе предварительной аутентификации, что повышает безопасность системы.

Путь к сертификату и закрытому ключу задается параметром ``pkinit_identity`` в файле ``/etc/krb5kdc/kdc.conf``. Значение по умолчанию:

-  Сертификат: ``/var/lib/ipa/certs/kdc.crt``.

-  Закрытый ключ: ``/var/lib/ipa/certs/kdc.key``.

Сертификат **KDC** используется не только для **PKINIT**, но и для других аспектов безопасности **Kerberos**, таких как двухфакторная аутентификация.

Сертификат **KDC** используется не только для **PKINIT**, но и для других аспектов безопасности **Kerberos**.

Обновление сертификата **KDC** рекомендуется выполнять в период планового технического обслуживания. Замена сертификата приводит к смене цепочки сертификатов аутентификации и старая цепочка должна быть доверенной в домене вплоть до замены (или обновления) сертификата на всех контроллерах.

Сервис Портала управления и API (Apache2)
---------------------------------------------

На базе веб-сервера **Apache2** реализованы следующие функции:

-  Портал управления службой каталогов — интерфейс для администрирования домена.

-  **REST API** — программный интерфейс для автоматизации задач.

Для обоих сервисов используется общий сертификат, расположенный по следующим путям:

-  Сертификат: ``/var/lib/ipa/certs/httpd.crt``.

-  Закрытый ключ: ``/var/lib/ipa/private/httpd.key``.

Основные сценарии управления сертификатами и использования сертификатов в домене ALD Pro
=============================================================================================

Управление цепочками доверия и сертификатами "на устройство"
----------------------------------------------------------------

Особенности выпуска сертификата "на устройство"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

В ALD Pro выпуск сертификатов для внутренних нужд домена (сертификаты сервисов контроллеров домена) выполняется службой **PKIProxy**.  

Служба предназначена для обработки запросов на выпуск и перевыпуск сертификатов через внешние или внутренние удостоверяющие центры.  

PKIProxy использует **LDAP** как транспорт, что обеспечивает надёжную сетевую связность между клиентом и сервисом даже в распределённых инфраструктурах.
Основные особенности **PKIProxy**:

-  Использует **LDAP** как транспорт, что обеспечивает надёжную сетевую связность между клиентом и сервисом.

-  Включен один плагин для локального **OpenSSL** **CA** (**Self-Signed CA-less**). Стандартный сценарий развертывания соответствует следующей диаграмме сертификатов (:numref:`certif-anqestry`).

.. figure:: medias/_fig_1.png
   :name: certif-anqestry
   
   Стандартная диаграмма наследования сертификатов

При развертывании с использованием промежуточного сертификата диаграмма выглядит следующим образом (:numref:`diag-anqestry`):

.. figure:: medias/_fig_2.png
   :name: diag-anqestry
   
   Диаграмма наследования сертификатов с промежуточным сертификатом

.. _change-cert-aldpro:

Замена сертификата домена ALD Pro
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

В случае необходимости выпуска нового сертификата домена (например, при компрометации действующего корневого сертификата или переходе на сторонний промежуточный УЦ), необходимо выполнить следующие шаги. Все операции должны выполняться на контроллере домена с действующим **Kerberos** билетом администратора домена и правами администратора:

.. code-block:: bash

   sudo -i
   kinit admin

Шаг 1: Подготовка переменных

Необходимо установить переменные и создать рабочую директорию для хранения новых сертификатов:

.. code-block:: bash

   export CLIENT="dc1.ald.company.lan"
   export REALM="ALD.COMPANY.LAN"
   mkdir -p newCA && cd newCA
   
Шаг 2: Генерация новых сертификатов

Для создания нового корневого сертификата УЦ (СА), необходимо сгенерировать запрос на сертификат для сервера, подписать его новым СА. Для этого выполняются следующие действия:

1. Создается новый корневой сертификат УЦ (CA):

   .. code-block:: bash

      openssl req -x509 -newkey rsa:2048 \
         -keyout ca.key -nodes \
         -out ca.crt \
         -subj "/CN=CA Signing Certificate2" \
         -days 7300

2. Генерируется запрос на сертификат для сервера:

   .. code-block:: bash

      openssl req -newkey rsa:2048 \
         -keyout server.key -nodes \
         -new \
         -out server.csr \
         -subj "/CN=$CLIENT" \
         -days 3650

3. Подписывается серверный сертификат новым CA:

   .. code-block:: bash

      openssl x509 -req \
         -in server.csr \
         -CA ca.crt \
         -CAkey ca.key \
         -CAcreateserial \
         -out server.crt \
         -days 3650 \
         -extfile /etc/ssl/pkinit_extensions.cnf \
         -extensions kdc_cert

Шаг 3: Установка нового сертификата СА

Необходимо выполнить проверку текущих сертификатов в **LDAP**, установить новый корневой сертификат и обновить его во всех хранилищах.

1. Проверить текущие сертификаты:

   .. code-block:: bash

      ipa-cacert-manage list

2. Установить новый сертификат УЦ (CA):

   .. code-block:: bash

      ipa-cacert-manage -n "CA Signing Certificate2" -t "C,," install ca.crt

3. Выполнить обновление сертификатов во всех хранилищах
   (**FreeIPA**, **DIRSRV** **NSSDB**, системное хранилище сертификатов):

   .. code-block:: bash

      ipa-certupdate

Шаг 4. Проверка установки:

.. code-block:: bash

   ipa-cacert-manage list

Для проверки записи сертификатов в NSS DB можно использовать команды:

.. code-block:: bash

   certutil -L -d /etc/dirsrv/slapd-ALD-COMPANY-LAN/ 
   certutil -d sql:/etc/ipa/nssdb -L -f /etc/ipa/nssdb/pwdfile.txt
   
Для проверки /etc/ipa/ca.crt необходимо использовать команду

.. code-block:: bash

   openssl crl2pkcs7 -nocrl -certfile /etc/ipa/ca.crt \
   openssl pkcs7 -print_certs -text -noout \
   less
   
Которая может отобразить больше одного сертификата в файле, если их несколько.

Команда ``ipa-certupdate`` пишет **CA** сертификат в ``/usr/local/share/ca-certificates``, откуда команда ``update-ca-certificates`` (которая вызывается из ``ipa-certupdate``) добавляет сертификат в цепочку доверенных сертификатов ``/etc/ssl/certs/ca-certificates.crt``, которая используется в **LDAP**.

Файл ``ca-certificates.crt`` является связкой сертификатов, в которой содержится более 100 корневых сертификатов удостоверяющих центров, которым доверяет операционная система **Astra Linux**. Корневой сертификат домена, который ранее отображался в файле ``/etc/ipa/ca.crt``, обычно находится в самом конце этого файла. Чтобы просмотреть системное хранилище сертификатов, после выполнения команды потребуется выполнить поиск по названию сертификата, например, **CA Signing**.

.. code-block:: bash

   openssl crl2pkcs7 -nocrl -certfile /etc/ssl/certs/ca-certificates.crt \
   openssl pkcs7 -print_certs -text -noout \
   less
   
Для минимизации ручных действий после обновления **СА** на контроллере домена необходимо обновить **CA** сертификат на клиенте домена. Важно выполнить обновление до перевыпуска сервисного сертификата **Apache**. Если нарушить последовательность, клиент не будет доверять новому сертификату службы (выпущенному обновленным **CA**), так как у него отсутствует информация о новом центре сертификации и потребуется ручное добавление нового **СА** на клиента. Для обновления сертификата СА на клиенте необходимо выполнить команду ``ipa-certupdate``, которая запишет цепочку сертификатов из **LDAP** в системное хранилище сертификатов.

Шаг 5: Установка серверного сертификата

При наличии клиентов в домене перед установкой нового серверного сертификата рекомендуется добавить новый **CA** сертификат на клиентах. Детальную информацию можно найти в разделе :ref:`client-cert-update`.

Чтобы установить серверный сертификат подписанный новым CA, необходимо выполнить команду, которая установит сертификаты для **DIRSRV**, **Apache**, **KDC** сервисов.

.. code-block:: bash

   ipa-server-certinstall -w -d -k --pin='' server.crt server.key

После установки нужно перезапустить **FreeIPA**.

.. code-block:: bash

   ipactl restart

Шаг 5: Проверка серверного сертификата

Для проверки сертификата **Apache** можно использовать следующую команду:

.. code-block:: bash

   echo Q \
   openssl s_client -showcerts dc1.ald.company.lan:443 \
   openssl x509 -noout -text \| grep -E "Issuer:\
   Subject:\|Not Before|Not After"

Для проверки сертификата **DIRSRV** для **LDAP** **StartTLS** и **LDAPS** используются команды:

1. **StartTLS**:

   .. code-block:: bash

      echo Q \
      openssl s_client -starttls ldap -showcerts dc1.ald.company.lan:389 \
      openssl x509 -noout -text \
      grep "Subject:"

2. **LDAPS**:

   .. code-block:: bash

      echo Q \
      openssl s_client -showcerts dc1.ald.company.lan:636 \
      openssl x509 -noout -text \
      grep "Subject:"

Для проверки сертификата **KDC** используются команды:

.. code-block:: bash

   openssl x509 -in /var/lib/ipa/certs/kdc.crt -text -noout \
   grep -E "Issuer:\|Subject:\
   Not Before|Not After"

На данном этапе все сертификаты сервисов должны быть выпущены от нового **CA**, в нашем случае **CA** **Signing Certificate2**, а новый **CA** должен присутствовать во всех хранилищах сертификатов.

Обновление сертификата на реплике
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Для обновления сертификатов на реплике потребуется получить Kerberos билет и действовать от имени администратора.

.. code-block:: bash

   sudo -i
   kinit admin

Для обновления **CA**-сертификата необходимо выполнить команду:

.. code-block:: bash

   ipa-certupdate

Эта команда подключится к **LDAP** реплики, скачает и установит обновленные **CA**-сертификаты, которые были получены в процессе репликации с основного контроллера домена.

На данном этапе серверный сертификат все еще выпущен старым УЦ, поэтому потребуется перевыпустить его от нового УЦ.

Для перевыпуска серверного сертификата необходимо воспользоваться функционалом **PKIProxy** домена **ALDPro**. Перед созданием запроса на новый сертификат необходимо изменить порядок сертификатов в файле ``/etc/ipa/ca.crt`` на хосте с установленной ролью **PKI Proxy**, в данном случае это **DC1**. Первым сертификатом должен быть новый УЦ (**CA2**). Для этого необходимо выполнить следующие шаги:

1. Разделить содержимое файла ``/etc/ipa/ca.crt`` на отдельные сертификаты:

   .. code-block:: bash

      mkdir -p /tmp/ca-split

      csplit -f /tmp/ca-split/part- -b "%02d.pem" /etc/ipa/ca.crt '/^-----BEGIN CERTIFICATE-----/' '{\*}'

2. Собрать сертификаты в новом порядке, где первым будет новый УЦ (**CA2**). Необходимо убедиться, что ``part-02.pem`` соответствует новому **CA** (**CA2**). Порядок частей (00, 01, 02) может отличаться в зависимости от системы и количества **CA**. Далее нужно проверить содержимое файлов ``part-\*.pem``, например, с помощью

   .. code-block:: bash

      openssl x509 -in part-XX.pem -text -noout \
      grep "Subject:"

чтобы выбрать правильный файл нового **CA** для позиции в начале. Далее сертификиты собираются в один файл командой

   .. code-block:: bash

      cat /tmp/ca-split/part-02.pem \
      /tmp/ca-split/part-00.pem \
      /tmp/ca-split/part-01.pem > /etc/ipa/ca.crt.new

3. После создания ``ca.crt.new`` необходимо создать резервную копию оригинального ``/etc/ipa/ca.crt`` и только потом заменить его новым файлом:

   .. code-block:: bash

      cp -p /etc/ipa/ca.crt /etc/ipa/ca.crt.bak
      mv /etc/ipa/ca.crt.new /etc/ipa/ca.crt
      
4. Далее нужно поместить приватный ключ нового УЦ (**CA2**) в файл ``/etc/ssl/freeipa/ca.key`` на хосте с установленной ролью **PKI Proxy**, в данном случае это **DC1**.

5. После подготовки конфигурации запускается процесс создания нового серверного сертификата с помощью команды:

   .. code-block:: bash

      aldpro-salt-call state.apply ssl_certs.states.get_crt

6. После завершения генерации сертификата установите его с помощью команды:

   .. code-block:: bash

      ipa-server-certinstall -w -d -k --pin='' /etc/ssl/certs/dc.crt /etc/ssl/certs/dc.key

.. _step7_freeipa_restart:

7. Требуется перезапустить службы **FreeIPA** для применения изменений:


   .. code-block:: bash

      ipactl restart

После успешного обновления вы можете проверить сертификаты на сервисах, используя команды из предыдущего раздела.

.. _client-cert-update:

Обновление сертификата на клиенте
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Оптимально обновить **CA** на клиенте после выпуска нового **CA** и перед выпуском новых сервисных сертификатов на **DC**. Для этого после выполнения команды на **DC**:

.. code-block:: bash

   ipa-cacert-manage -n "CA Signing Certificate2" -t "C,," install ca.crt

которая запишет новый **CA** в **LDAP**, на клиенте выполняется команда ``ipa-certupdate``, которая запишет цепочку сертификатов из **LDAP** с новым **CA** в системное хранилище сертификатов клиента.

В случае если обновить **СА** и сервисный сертификат на **Apache** на **DC**, при попытке выполнения команды ``ipa-certupdate`` на клиенте может возникнуть ошибка ``SSL: CERTIFICATE_VERIFY_FAILED``, так как сертификат на сервисе Apache на DC выпущен СА, которому клиент не доверяет.

Чтобы клиент смог обратиться к **DC**, следует добавить новый **СА** -сертификат на клиент по пути ``/etc/ipa/ca.crt`` и выполнить команду ``ipa-certupdate``. Это команда загрузит корневые сертификаты из **LDAP** и добавит их в системное хранилище, ``/etc/ipa/ca.cert`` и **IPA** **NSSDB**. После этого клиент начнет доверять новому **CA** и сможет взаимодействовать с **DC** в штатном режиме.

Сертификаты подсистем ALD Pro
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

В таблице ниже приведены пути до сертификатов и ключей на серверах с установленной подсистемой.

.. list-table:: Сертификаты подсистем
   :name: subsystem-certificates
   :widths: 34 33 33
   :header-rows: 1
   :class: longtable

   * - Подсистема
     - Путь до сертификата
     - Путь до ключа
   * - Установка ОС по сети
     - /etc/ssl/certs/os.crt
     - /etc/ssl/certs/os.key
   * - Сетевого репозитория
     - /etc/ssl/certs/repo.crt
     - /etc/ssl/certs/repo.key
   * - Мониторинга
     - /etc/ssl/certs/zabbix.crt
     - /etc/ssl/certs/zabbix.key
   * - Сервера печати
     - /etc/ssl/certs/cups.crt
     - /etc/ssl/certs/cups.key
   * - Реплика DC
     - /etc/ssl/certs/dc.crt
     - /etc/ssl/certs/dc.key

Выпуск промежуточного сертификата для домена ALD Pro на Microsoft CA
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Для выпуска сертификата домена **ALD Pro** на удостоверяющем центре **Microsoft** **CA**, необходимо выполнить следующие шаги:

Шаг 1: Создание ключа и запроса сертификата

Выполняется создание нового ключа и запрос на выпуск сертификата:

.. code-block:: bash

   # openssl req -newkey rsa:2048 -keyout new_ca.key -nodes -out new_ca.csr -subj "/CN=CA Signing Certificate 3"

Шаг 2: Выпуск сертификата на сервере **MS** **CA**

Для выпуска сертификата необходимо выполнить следующую команду на сервере
центра сертификации **Microsoft**:

.. code-block:: console

   # certreq -attrib "CertificateTemplate:SubCA" .\new_ca.csr

В случае успешной обработки запроса вывод будет содержать идентификатор
запроса и статус его выдачи, например:

.. code-block:: console

   RequestId: "4"
   Certificate retrieved(Issued) Issued

.. note:: 

   Срок действия выпускаемого сертификата зависит от настроенного шаблона и политики выпуска сертификатов **MS** **CA** (по умолчанию 2 года). Это важно учитывать при эксплуатации. Для получения справки по использованию шаблонов и политик выпуска сертификатов обратитесь к документации по **MS** **CA**.

Шаг 3: Импорт сертификатов в ALD Pro

Перед импортом необходимо экспортировать сертификат и всю цепочку доверия
центра сертификации (**CA**) в формате **PEM** (``Base64``) и сохранить файлы
на контроллере домена **ALD Pro**.

Импорт сертификатов выполняется последовательно — от корневого сертификата
(``root`` **CA**) к промежуточному (**SubCA**).

1. Установить корневой сертификат **CA**:

   .. code-block:: bash

      # ipa-cacert-manage -t C,, install ./winad_root_ca.crt

   Пример успешного выполнения:

   .. code-block:: console

      Installing CA certificate, please wait
      Verified CN=domain-WINAD-01-CA,DC=domain,DC=test
      CA certificate successfully installed
      The ipa-cacert-manage command was successful

2. Установить промежуточный сертификат (**SubCA**):

   .. code-block:: bash

      # ipa-cacert-manage -t C,, install ./new_ca.crt

   Пример успешного выполнения:

   .. code-block:: console

      Installing CA certificate, please wait
      Verified CN=CA Signing Certificate 3
      CA certificate successfully installed

Далее можно выполнить обновление сертификатов домена и контроллеров согласно разделам :ref:`change-cert-aldpro`.

Примечание: Если возникают проблемы с выполнением команды ipa-certupdate, нужно скопировать содержимое файла ``/etc/ipa/ca.crt`` в аналогичный файл на клиенте домена.

Данный раздел применим, в части импорта сертификата для **ALD Pro**, к любому другому УЦ, за исключением порядка выпуска сертификата. За дополнительными подробностями необходимо обращаться в руководство администратора УЦ или в техническую поддержку его производителя.

Двухфакторная аутентификация: Kerberos PKINIT
-------------------------------------------------

В данном разделе рассматривается процесс создания промежуточного сертификата с помощью инструментов **OpenSSL** и его использование для выпуска сертификатов пользователей для **PKINIT**. Диаграмма наследования сертификатов приведена на  (:numref:`diag-anq`).

.. figure:: medias/_fig_3.png
   :name: diag-anq
   
   Диаграмма наследования сертификатов

Для работы с сертификатами потребуются следующие компоненты:

-  Самоподписанный корневой сертификат **FreeIPA** (``/etc/ssl/freeipa/ca.crt``) и его приватный ключ (``/etc/ssl/freeipa/ca.key``).

-  Установленный **OpenSSL**.

-  Базовые знания о конфигурационных файлах **OpenSSL**.

-  Выполнение команд произведено на **ALSE 1.7.6 uu2** и **ALD Pro 2.4.0**, при использовании других версий команды и их порядок могут отличаться.

Создание промежуточного сертификата (Sub CA)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Создание приватного ключа для Sub CA
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Необходимо создать папку ``/etc/ssl/freeipa/intermediate`` и перейти в нее с помощью команд:

.. code-block:: bash

   sudo mkdir /etc/ssl/freeipa/intermediate
   cd /etc/ssl/freeipa/intermediate
   
Необходимо создать приватный ключ для промежуточного сертификата:

.. code-block:: bash

   openssl genpkey -algorithm RSA -out subca.key -aes256

Эта команда сгенерирует защищённый паролем приватный ключ формата **RSA** длиной 2048 бит.

Создание запроса на подпись (CSR) для Sub CA
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Необходимо создать запрос на выпуск промежуточного сертификата:

.. code-block:: bash

   openssl req -new -key subca.key -out subca.csr -subj "/CN=IntermediateCA"

Здесь ``/CN=IntermediateCA`` — это имя промежуточного сертификата. Его можно заменить на любое другое уникальное имя.

Подпись CSR корневым сертификатом
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Для выпуска промежуточного сертификата необходимо выполнить подпись
запроса (**CSR**) корневым сертификатом центра сертификации.

1. Необходимо создать конфигурационный файл ``subca.conf`` со следующим содержимым:

   .. code-block:: ini

      [ ca ]
      default_ca = root_ca

      [ root_ca ]
      private_key = /etc/ssl/freeipa/ca.key
      certificate = /etc/ssl/freeipa/ca.crt
      new_certs_dir = /etc/ssl/freeipa/intermediate # Директория для хранения новых сертификатов
      database = index.txt # Файл базы данных сертификатов
      serial = serial # Файл для отслеживания серийных номеров
      default_md = sha256 # Хэш-функция по умолчанию
      policy = policy_loose # Политика подписи

      [ policy_loose ]
      commonName = supplied # CN должен быть указан
      stateOrProvinceName = optional # Регион/область опциональны
      countryName = optional # Страна опциональна
      emailAddress = optional # Email опционален
      organizationName = optional # Организация опциональна
      organizationalUnitName = optional # Отдел опционален

      [ v3_intermediate_ca ]
      subjectKeyIdentifier = hash
      authorityKeyIdentifier = keyid:always,issuer
      basicConstraints = critical, CA:true, pathlen:0
      keyUsage = critical, digitalSignature, cRLSign, keyCertSign

2. Необходимо создать необходимые вспомогательные файлы:

   .. code-block:: bash

      touch index.txt
      echo 1000 > serial

3. Необходимо выполнить подпись **CSR** корневым сертификатом и выпустить промежуточный сертификат:

   .. code-block:: bash

      openssl ca \
         -config subca.conf \
         -extensions v3_intermediate_ca \
         -days 365 \
         -notext \
         -md sha256 \
         -in subca.csr \
         -out subca.crt

В результате выполнения команды будет создан промежуточный сертификат
``subca.crt``.

Параметр ``private_key`` указывает путь к приватному ключу корневого CA.
Параметр ``certificate`` указывает путь к корневому сертификату.

Создание цепочки доверия
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Чтобы клиенты могли проверять подлинность промежуточного сертификата, необходимо скомпилировать его вместе с корневым сертификатом в одну цепочку:

.. code-block:: bash

   cat subca.crt ../ca.crt > ca-chain.pem

Этот файл (ca-chain.pem) можно распространять среди клиентов для установления доверия.

.. _rec_sub_ca_2_ldap:

Запись Sub CA в LDAP
~~~~~~~~~~~~~~~~~~~~~~~~

Для того, чтобы **Kerberos** доверял промежуточному сертификату потребуется выполнить ряд операций, которые добавят промежуточный сертификат в базу данных доверенных сертификатов, для начала нужно выполнить команду, которая запишет сертификат в **LDAP** по пути ``DN``: ``cn=CN\\3DIntermediateCA,cn=certificates,cn=ipa,cn=etc,dc=ald,dc=company,dc=lan:``

.. code-block:: bash

   ipa-cacert-manage  -t C,, install subca.crt

Флаг доверия C означает что сертификат является доверенным УЦ для выпуска сертификатов на устройство.

Для просмотра текущих сертификатов в базе данных **NSSDB** можно воспользоваться утилитой:

.. code-block:: bash

   certutil -L -d /etc/dirsrv/slapd-ALD-COMPANY-LAN/

Далее выполняется команда и еще раз проверяется содержимое базы данных **NSSDB**:

.. code-block:: bash
   
   ipa-certupdate
   certutil -L -d /etc/dirsrv/slapd-ALD-COMPANY-LAN/

Команда ``ipa-certupdate`` выполняет обновление сертификатов, загружая информацию из **LDAP**, которые находятся на сервере по путям:

.. code-block:: text

   /etc/ipa/ca.crt
   /var/lib/ipa-client/pki/ca-bundle.pem
   /var/lib/ipa-client/pki/kdc-ca-bundle.pem
   
А также добавит сертификат в **NSSDB**. Данную команду требуется выполнить на всех серверах и клиентах домена. После выполнения команды обновятся сертификаты ``ca-bundle.pem`` и ``kdc-ca-bundle.pem``, которые используются в **Kerberos** **PKINIT**, тем самым отсутствует необходимость явного указания промежуточного сертификата в конфигурационном файле ``krb5.conf``.

Генерация сертификата пользователя подписанного Sub CA
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Подготовка
^^^^^^^^^^^^^^

На клиенте и сервере должны быть установлены следующие пакеты из репозитория **Astra Linux**:

.. code-block:: bash

   sudo apt install libccid pcscd \ 
   libpcsclite1 pcsc-tools opensc \
   krb5-pkinit libpam-krb5 \
   libengine-pkcs11-openssl1.1 csp-monitor

Для обеспечения возможности обращения к смарт-карте Рутокен ЭЦП, на клиенте и сервере следует установить стороннюю библиотеку ``librtpkcs11ecp.so``, доступную на официальном сайте производителя токенов **Рутокен** - ``https://www.rutoken.ru/support/download/pkcs/``:

.. code-block:: bash

   dpkg -i librtpkcs11ecp_2.17.1.0-1_amd64.deb

Выполняется команда, указав актуальное расположение библиотеки:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Проверка работы **РуТокена**:

.. code-block:: bash

   pkcs11-tool --module /usr/lib/librtpkcs11ecp.so –T

Пример вывода команды

.. code-block:: console

   Available slots:
   Slot 0 (0x0): Aktiv Rutoken ECP 00 00
      token label : Rutoken
      token manufacturer : Aktiv Co.
      token model : Rutoken ECP
      token flags : login required, rng, SO PIN to be changed, token initialized, PIN initialized, user PIN to be changed
      hardware version : 54.1
      firmware version : 23.2
      serial num : 44444444
      pin min/max : 6/32
   
Если токен был использован ранее, выполняется очистка токена с помощью утилиты ``rtadmin``. Скачать можно с `официального сайта производителя: <https://www.rutoken.ru/support/download/get/rtAdmin-linux.html>`_.

После распаковки архива выполняется команда, которая сбросит все настройки токена и установит ПИН пользователя (-u) и администратора (-a):

.. code-block:: bash

   ./rtadmin -f -p 3 -L Rutoken -u 12345678 -a 87654321

Инициализация ``rutoken`` инструментом pkcs11-tool.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Инициализация ``rutoken`` выполняется следующей командой:


.. code-block:: bash

   pkcs11-tool --slot 0 --init-token \
   --so-pin 87654321 --label 'Token' \
   --module /usr/lib/librtpkcs11ecp.so

Здесь:

--slot 0 — указывает, в какой виртуальный слот подключено устройство. Как правило, это слот 0, но могут быть и другие значения - 1,2 и т.д.;

--init-token - команда инициализации токена;

--so-pin 87654321 - PIN-код администратора Рутокен ЭЦП. По умолчанию имеет значение 87654321;

--label 'Token' - название устройства;

--module /usr/lib/librtpkcs11ecp.so — указывает путь до библиотеки ``librtpkcs11ecp.so``.

Присвоение PIN-кода для токена
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Задание PIN-кода осуществляется командой:


.. code-block:: bash

   pkcs11-tool --slot 0 --init-pin \
   --so-pin '87654321' --login \
   --pin '12345678' \
   --module /usr/lib/librtpkcs11ecp.so

Здесь:

--init-pin - команда установки PIN-кода пользователя;

--login - команда входа в токен;

--pin 12345678 - задаваемый PIN-код пользователя;

Генерации ключей на устройстве
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Генерация ключей выполняется при помощи команды:

.. code-block:: bash

   pkcs11-tool --slot 0 --login \
   --pin 12345678 --keypairgen \
   --key-type rsa:2048 --id 54 \
   --label "user_keys" \
   --module /usr/lib/librtpkcs11ecp.so

Здесь:

--keypairgen --key-type rsa:2048 — указывает, что должны быть созданы **RSA** ключи длиной 2048 бит;

--id 54 — устанавливает атрибут ``CKA_ID`` ключа. ``CKA_ID`` может быть любым;

--label “user_keys” — устанавливает атрибут ``CKA_LABEL``(имя) ключа. Атрибут может быть любым.

Генерация запроса на сертификат
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Для генерации запроса на сертификат в среде ALSE 1.7 ( openssl 1.1)  необходимо использовать команду:

.. code-block:: bash

   openssl
   engine dynamic \
   -pre SO_PATH:/usr/lib/x86_64-linux-gnu/engines-1.1/pkcs11.so \
   -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD \
   -pre MODULE_PATH:/usr/lib/librtpkcs11ecp.so
   req -engine pkcs11 -new -key 0:54 -keyform engine -out user.req
   
В запросе указывается необходимая информация о сертификате, особое внимание требуется уделить полям ``Common Name`` куда следует указать имя учетной записи для которой генерируется сертификат, а также ``Email Address`` учетной записи.

Проверка файла
^^^^^^^^^^^^^^^^^^^

Необходимо убедиться, что созданный файл ``user.req`` находится на контроллере домена, где присутствуют промежуточные сертификат ``subca.crt`` и ключ ``subca.key``.

Подпись запроса на выдачу сертификата на контроллере домена 
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Чтобы подписать запрос на выдачу сертификата на контроллере домена (см. :ref:`шаг 7 (перезапуск FreeIPA) <step7_freeipa_restart>`) необходимо выполнить следующее:

1) Установить переменные окружения:

.. code-block:: bash

   export REALM=ALD.COMPANY.LAN - имя домена заглавными буквами
   export CLIENT=user - имя УЗ из домена
   
2) Для того, чтобы убедиться, что переменные указаны верно, использовать команду:

.. code-block:: bash

   env \
   grep -E "REALM|CLIENT"

3) Файл pkinit_extensions скачивается на контроллер домена:

Файл ``pkinit_extensions`` используется для задания расширений сертификата, применяемых в **Kerberos** **PKINIT**.
Он определяет, как **KDC** и клиенты обрабатывают и интерпретируют данные сертификата.

Файл состоит из нескольких секций, задающих правила для сертификатов **KDC** и клиентов, а также вспомогательные секции, определяющие структуру вложенных данных.

.. code-block:: ini

   [ kdc_cert ]
   basicConstraints=CA:FALSE
   keyUsage = nonRepudiation, digitalSignature, keyEncipherment, keyAgreement
   extendedKeyUsage = 1.3.6.1.5.2.3.5
   subjectKeyIdentifier=hash
   authorityKeyIdentifier=keyid,issuer
   issuerAltName=issuer:copy
   subjectAltName=otherName:1.3.6.1.5.2.2;SEQUENCE:kdc_princ_name

   [kdc_princ_name]
   realm = EXP:0, GeneralString:${ENV::REALM}
   principal_name = EXP:1, SEQUENCE:kdc_principal_seq

   [kdc_principal_seq]
   name_type = EXP:0, INTEGER:1
   name_string = EXP:1, SEQUENCE:kdc_principals

   [kdc_principals]
   princ1 = GeneralString:krbtgt
   princ2 = GeneralString:${ENV::REALM}

   [ client_cert ]
   basicConstraints=CA:FALSE
   keyUsage = digitalSignature, keyEncipherment, keyAgreement
   extendedKeyUsage = 1.3.6.1.5.2.3.4
   subjectKeyIdentifier=hash
   authorityKeyIdentifier=keyid,issuer
   issuerAltName=issuer:copy
   subjectAltName=otherName:1.3.6.1.5.2.2;SEQUENCE:princ_name

   [princ_name]
   realm = EXP:0, GeneralString:${ENV::REALM}
   principal_name = EXP:1, SEQUENCE:principal_seq

   [principal_seq]
   name_type = EXP:0, INTEGER:1
   name_string = EXP:1, SEQUENCE:principals

   [principals]
   princ1 = GeneralString:${ENV::CLIENT}


Описание секций и параметров
----------------------------

.. list-table:: Параметры pkinit_extensions
   :header-rows: 1
   :widths: 30 70
   :class: longtable

   * - **Секция / Параметр**
     - **Назначение**

   * - **kdc_cert**
     - 

   * - basicConstraints
     - Определяет, что сертификат KDC не является центром сертификации (CA:FALSE)
   * - keyUsage
     - Определяет допустимые операции ключа: nonRepudiation, digitalSignature, keyEncipherment, keyAgreement
   * - extendedKeyUsage
     - OID 1.3.6.1.5.2.3.5 (**PKINIT** **KDC**)
   * - subjectKeyIdentifier
     - Генерация идентификатора открытого ключа (хеш)
   * - authorityKeyIdentifier
     - Связь с сертификатом издателя (keyid, issuer)
   * - issuerAltName
     - Копирование информации об издателе в SAN
   * - subjectAltName
     - SAN для KDC, KerberosPrincipalName (RFC 4556), содержащий имя KDC-принципала, формируется на основе секции [kdc_princ_name]

   * - **kdc_princ_name**
     - 

   * - realm
     - Kerberos-реалм, берется из переменной окружения REALM
   * - principal_name
     - Имя принципала, формируется по секции [kdc_principal_seq]

   * - **kdc_principal_seq**
     - 

   * - name_type
     - Тип имени принципала (INTEGER:1) Kerberos (см. RFC 4120). Значение 1 соответствует KRB_NT_PRINCIPAL.
   * - name_string
     - Последовательность имени из [kdc_principals]

   * - **kdc_principals**
     - 

   * - princ1
     - Первая компонента KDC-принципала: krbtgt
   * - princ2
     - Вторая компонента: Kerberos-реалм (${ENV::REALM})

   * - **client_cert**
     - 

   * - basicConstraints
     - Сертификат клиента не является CA
   * - keyUsage
     - Допустимые операции: digitalSignature, keyEncipherment, keyAgreement
   * - extendedKeyUsage
     - OID 1.3.6.1.5.2.3.4 (PKINIT Client)
   * - subjectKeyIdentifier
     - Идентификатор открытого ключа (hash)
   * - authorityKeyIdentifier
     - Связь с сертификатом издателя
   * - issuerAltName
     - Копирование информации об издателе
   * - subjectAltName
     - SAN для клиента, формируется по секции [princ_name]

   * - **princ_name**
     - 

   * - realm
     - Kerberos-реалм клиента (${ENV::REALM})
   * - principal_name
     - Имя клиентского принципала, формируется по секции [principal_seq]

   * - **principal_seq**
     - 

   * - name_type
     - Тип имени принципала клиента (INTEGER:1) 
   * - name_string
     - Последовательность имени из секции [principals]

   * - **principals**
     - 

   * - princ1
     - Имя клиентского принципала (${ENV::CLIENT})

4) Выпускается сертификат пользователя, подписанный промежуточным сертификатом:

.. code-block:: bash

   sudo -E openssl x509 \
   -CAkey /etc/ssl/freeipa/intermediate/subca.key \
   -CA /etc/ssl/freeipa/intermediate/subca.crt \
   -req -in user.req -extensions client_cert \
   -extfile pkinit_extensions -out user.pem \
   -days 365 –CAcreateserial

5) Проверка валидности сертификата с использованием цепочки сертификатов (``root ca`` + ``sub ca``) выполняется при помощи команды:

.. code-block:: bash

   openssl verify -verbose -CAfile /etc/ssl/freeipa/intermediate/ca-chain.pem user.pem

Если проверка прошла успешно, то вывод будет иметь вид:

.. code-block:: console

   user.pem: OK

6) Далее полученный сертификат перекодируется из формата **PEM** в формат **DER**:

Перекодирование полученного сертификата выполняется командой:

.. code-block:: bash

   sudo openssl x509 -in user.pem -out user.cer -inform PEM -outform DER

7) В результате успешного выполнения предыдущих действий в папке, откуда запускались команды из шага 4, должно появиться два файла: ``user.pem`` и ``user.cer``.

8) Необходимо выполнить добавление данных сертификатов

Для этого используются следующие команды:

.. code-block:: bash

   kinit admin
   ipa user-add-cert user --certificate="$(grep -v ^---- user.pem)"

9) Далее полученный сертификат записывается на токен:

Запись выполняется следующей командой:

.. code-block:: bash

   pkcs11-tool --slot 0 --login \
   --pin 12345678 --write-object user.cer \
   --type 'cert' --label 'user_key' --id 54 \
   --module /usr/lib/librtpkcs11ecp.so

Здесь используются следующие ключи:

--write-object user.cer — указывает, что необходимо записать объект и путь до него;

--type 'cert'— указывает, что тип записываемого объекта - сертификат;

--label 'user_key' — устанавливает атрибут CKA_LABEL(имя) сертификата. Атрибут может быть любым.

10) Необходимо отредактировать файл ``/etc/krb5.conf``:

Редактирование заключается в добавлении строк:
- ``pkinit_identities`` для указания библиотеки для работы с токеном; 
- ``pkinit_pool`` для указания доверенного промежуточного сертификата или цепочки сертификатов. Указывать ``pkinit_pool`` не обязательно если промежуточный сертификат добавлен в БД сертификатов LDAP и на конечном устройстве выполнена команда ``ipa-certupdate``, см. :ref:`rec_sub_ca_2_ldap`.

.. code-block:: ini

   [libdefaults]
   
   # для аутентификации по токену для всех доменов. Если необходимо только для одного, указать эту строчку в разделе realm, как в шаге 16
   
.. code-block:: ini

   pkinit_identities = PKCS11:/usr/lib/librtpkcs11ecp.so
   pkinit_pool = FILE:/etc/ssl/freeipa/intermediate/ca-chain.pem #не требуется если выполнена команда ipa-certupdate
   
11) По умолчанию SSSD использует правила соответствия и сопоставления сертификатов вида:

.. code-block:: ini

   #define DEFAULT_MATCH_RULE "<KU>digitalSignature<EKU>clientAuth"
   #define DEFAULT_MAP_RULE "LDAP:(userCertificate;binary={cert!bin})"
   
Для использования данных правил, требуется, чтобы расширения сертификата ``key usage`` и ``extended key usage`` включали ``digitalSignature`` и ``clientAuth`` соответственно. Если используется pkinit_extensions файл рекомендуемый `MIT Kerberos <https://web.mit.edu/kerberos/krb5-1.21/doc/admin/pkinit.html#generating-client-certificates>`__, то extended key usage содержит значение KPClientAuth и при попытке вызова функции kinit, будет возвращена ошибка certificate mismatch из-за отсутствия подходящего правила в SSSD для сертификата.

Для устранения данного вопроса требуется создать явное правило соответствия и сопоставления сертификатов, о чем более детально можно ознакомиться в `статье <https://manpages.debian.org/experimental/libsss-certmap0/sss-certmap.5.en.html>`__. Ниже приведён пример создания правила при условии, что сертификат пользователя в расширении ``extended key usage`` имеет значение ``KPClientAuth`` с ``OID`` 1.3.6.1.5.2.3.4:

.. code-block:: console

   X509v3 Extended Key Usage: PKINIT Client Auth

Поэтому правило будет выглядеть следующим образом:

.. code-block:: bash

   ipa certmaprule-add mappingrule \
   --matchrule='<EKU>KPClientAuth' \
   --maprule='(userCertificate;binary={cert!bin})'

после добавления выполняется перезагрузка сервисов:

.. code-block:: bash

   sudo aldproctl restart

12) После перезагрузки выполняется проверка работоспособности приложения:

Проверка выполняется на основе следующей команды:

.. code-block:: bash

   env KRB5_TRACE=/dev/stdout kinit user

Потребуется ввести ``pin`` пользователя токена, при выполнении команды ``klist`` должен отобразиться Kerberos билет на пользователя ``user``. При использовании токена на клиентском устройстве потребуется установить библиотеку для работы с токеном и вспомогательные пакеты:

.. code-block:: bash
   
   apt install krb5-pkinit libccid pcscd
   dpkg -i librtpkcs11ecp_2.17.1.0-1_amd64.deb
   
Также перенести цепочку сертификатов ``ca-chain.pem`` и указать в ``krb5.conf`` файле, как это сделано в шаге 10, либо и более предпочтительно выполнить шаги описанные в :ref:`rec_sub_ca_2_ldap`.
